/*
* Copyright (C) 2024 ~ 2025 Uniontech Technology Co., Ltd.
*
* Author:      zhangbingyi <zhangbingyi@uniontech.com>
*
* Maintainer:  zhangbingyi <zhangbingyi@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "virusfiledetaildelegate.h"
#include "virusfiledetaildefinition.h"

//#include <DFontSizeManager>
//#include <DApplicationHelper>

#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QToolTip>

VirusFileDetailDelegate::VirusFileDetailDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

void VirusFileDetailDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem itemOption(option);

    if (index.row() % 2 == 0) {
        QPalette pl(qApp->palette());
        QPainterPath path;
        if (index.column() == COLUMN_RISKS) {
            path.setFillRule(Qt::WindingFill);
            path.addRoundedRect(option.rect, 12, 12);
            QRect temp_rect(option.rect.left() + 20, option.rect.top(), option.rect.width() - 20, option.rect.height());
            path.addRect(temp_rect);
            painter->fillPath(path, pl.brush(QPalette::Background));
        } else if (index.column() == COLUMN_SUGGESTION) {
            painter->fillRect(option.rect, pl.brush(QPalette::Background));
        } else if (index.column() == COLUMN_OPERATION) {
            path.setFillRule(Qt::WindingFill);
            path.addRoundedRect(option.rect, 12, 12);
            QRect temp_rect(option.rect.left(), option.rect.top(), option.rect.width() / 2, option.rect.height());
            path.addRect(temp_rect);
            painter->fillPath(path, pl.brush(QPalette::Background));
        }
    }

    // 第0列添加checkbox
    if (COLUMN_RISKS == index.column()) {
        painter->save();
        bool isChecked = index.model()->data(index, ROLE_CHECKED_STATUS).toBool();

        QModelIndex tmpIndex = index.model()->index(index.row(), COLUMN_OPERATION);
        bool operaFlag = index.model()->data(tmpIndex, ROLE_OPERATION_FLAG).toBool();
        if (operaFlag) {
            painter->setOpacity(0.5);
        } else {
            painter->setOpacity(1);
        }

        QStyleOptionButton checkBox;

        checkBox.state = isChecked ? QStyle::State_On : QStyle::State_Off;
        checkBox.state |= QStyle::State_Enabled;

        QRect tmp = itemOption.rect;
        tmp.setX(tmp.x() + 10);
        tmp.setY(tmp.y() + 14);
        tmp.setWidth(CHECKBOX_SIZE);
        tmp.setHeight(CHECKBOX_SIZE);
        checkBox.rect = tmp;
        QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBox, painter);
        painter->restore();

        itemOption.rect = option.rect.adjusted(30, 10, 0, 0);

        painter->save();

        // 绘制路径及文件名
        if (operaFlag) {
            painter->setOpacity(0.5);
        } else {
            painter->setOpacity(1);
        }
        QString filePath = index.model()->data(index, ROLE_VIRUSFILE_PATH).toString();
        QString fileName = index.model()->data(index, ROLE_VIRUSFILE_NAME).toString();
        int currentFontSize = qApp->font().pointSize();
        QFont font;
        font.setPixelSize(currentFontSize);
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x() + 10, textRect.y() + 10);
        painter->setFont(font);
        QFontMetrics fontWidth(font);
        filePath = fontWidth.elidedText(filePath, Qt::ElideMiddle, itemOption.rect.width() - 10);
        fileName = fontWidth.elidedText(fileName, Qt::ElideMiddle, itemOption.rect.width() - 10);
        painter->drawText(textPoint, filePath);
        textPoint.setY(textPoint.y() + currentFontSize + 10);
        painter->drawText(textPoint, fileName);
        painter->restore();
    }
    if (itemOption.state & QStyle::State_HasFocus) {
        itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
    }

    QStyledItemDelegate::paint(painter, itemOption, index);
}

bool VirusFileDetailDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QMouseEvent *mouse = static_cast<QMouseEvent *>(event);
    QModelIndex tmpIndex = model->index(index.row(), COLUMN_OPERATION);
    if (event->type() == QEvent::MouseButtonRelease && option.rect.contains(mouse->pos())) {
        if (index.column() == COLUMN_RISKS && !model->data(tmpIndex, ROLE_OPERATION_FLAG).toBool()) {
            bool checkState = model->data(index, ROLE_CHECKED_STATUS).toBool();
            model->setData(index, !checkState, ROLE_CHECKED_STATUS);
            Q_EMIT sendCheckClickSingal();
        }
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

bool VirusFileDetailDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::ToolTip) {
        if (index.column() == COLUMN_RISKS) {
            QStyleOptionViewItem itemOption(option);
            QRect rect = itemOption.rect;

            QRect filePathRect(rect.x() + 40, rect.y() + 10, itemOption.rect.width() - 50, option.fontMetrics.height());
            QRect fileNameRect(rect.x() + 40, rect.y() + option.fontMetrics.height() + 10,
                               itemOption.rect.width() - 50, option.fontMetrics.height());
            QString tooltip;
            if (filePathRect.contains(event->pos())) {
                tooltip = index.data(ROLE_VIRUSFILE_PATH).toString();
            } else if (fileNameRect.contains(event->pos())) {
                tooltip = index.data(ROLE_VIRUSFILE_NAME).toString();
            } else {
                QWidgetList qwl = QApplication::topLevelWidgets();
                for (QWidget *qw : qwl) {
                    if (QString("QTipLabel") == qw->metaObject()->className()) {
                        qw->close();
                    }
                }
            }
            QToolTip::showText(event->globalPos(), tooltip);
            return true;
        }
    }
    return QStyledItemDelegate::helpEvent(event, view, option, index);
}
